<!-- 公共组件-百度地图GL -->
<template>
  <div class="box">
    <div id="container" @click="getMapObj"></div>
    <slot></slot>
  </div>
</template>
<script>
import {lazyBMapApiLoaderInstance} from 'vue-bmap-gl'

export default {
  name: 'bMap',
  props: {
    // 初始地图中心坐标
    centerPoint: {
      type: Object,
      default: () => ({
        id: '',
        name: '吴宁一中',
        point: ['120.244642', '29.271818']
      }),
      required: false
    },
    // 覆盖物坐标
    polygon: {
      type: Array,
      default: () => [
        {
          id: '',
          arr: [
            [120.24769, 29.271098],
            [120.248929, 29.271129],
            [120.249001, 29.27046],
            [120.249298, 29.270467],
            [120.249513, 29.26994],
            [120.248148, 29.269609],
            [120.24769, 29.271098]
          ]
        }, {
          id: '',
          arr: [
            [120.243396, 29.272248],
            [120.243517, 29.271381],
            [120.243391, 29.271346],
            [120.243427, 29.270909],
            [120.246064, 29.271192],
            [120.245897, 29.273035],
            [120.245543, 29.273271],
            [120.244038, 29.272389],
            [120.243396, 29.272271]
          ]
        }
      ],
      required: false
    },
    // 标点坐标
    point: {
      type: Array,
      default: () => [
        {
          id: '073D0053-6CBB-4553-AD26-7AB82BF15217',
          name: '吴宁一中',
          imgColor: null,
          point: ['120.244642', '29.271818']
        }, {
          id: '',
          name: '三单乡中小学(小学部)',
          imgColor: null,
          point: ['120.633874', '29.295942']
        }
      ],
      required: false
    },
    // 覆盖物全部清除标志
    clearOverlays: {
      type: Object,
      default: () => ({
        flag: false
      })
    }
  },
  data () {
    return {
      // 地图对象
      map: null,
      // 颜色索引
      colorIndex: -1,
      // 颜色值
      color: '#D82109',
      // 页面首次加载标记
      firstLoad: 0,
      // 覆盖物颜色
      polygonColor: [],
      // 当前点击的标点ID
      markerId: '',
      // 多边形覆盖物删除标记
      polygonDelFlag: true,
      // 多边形覆盖物id数组
      polygonIdArr: []
    }
  },
  watch: {
    polygon: {
      handler (newVal) {
        console.log('polygon______')
        this.polygonDelFlag = true
        this.delOverlays(newVal, 'polygon')
        if (this.polygonDelFlag) {
          this.color = this.getRandomColor()
          this.polygonColor.push(this.color)
          this.addPolygon(this.map, newVal)
        }
      },
      immediate: true,
      // 开启深度监听 deep
      deep: true
    },
    point: {
      handler (newVal) {
        if (newVal.length > 0) {
          setTimeout(() => {
            console.log('point______')
            this.addPoint(this.map, newVal)
          }, 2000)
        }
      },
      immediate: true,
      // 开启深度监听 deep
      deep: true
    },
    centerPoint: {
      handler (newVal) {
        if (newVal.id !== undefined) {
          console.log('centerPoint______')
          this.setMapCenter(newVal)
          if (this.firstLoad !== 0) {
            this.delOverlays(newVal, 'point')
            this.addOnePoint(newVal, this.polygonDelFlag, this)
            this.markerId = newVal.id
          }
          if (!this.$props.clearOverlays.flag) {
            this.firstLoad = 1
          } else {
            this.firstLoad--
          }
          this.setMapStyle()
        }
      },
      immediate: true,
      // 开启深度监听 deep
      deep: true
    },
    clearOverlays: {
      handler (newVal) {
        if (newVal.flag === true) {
          console.log('clearOverlays______')
          if (this.map) {
            this.map.clearOverlays()
          }
          this.polygonDelFlag = false
        }
      },
      immediate: true,
      // 开启深度监听 deep
      deep: false
    }
  },
  methods: {
    // 地图初始化
    initBMap () {
      console.log('initBMap______')
      lazyBMapApiLoaderInstance.load().then(() => {
        // 创建地图实例
        // eslint-disable-next-line no-undef
        const map = new BMapGL.Map('container')
        this.map = map
        // 设置鼠标滚动监听
        window.addEventListener('mousewheel', this.handleScroll, false)
        // 初始化地图，设置初始中心点坐标和地图级别
        if (this.$props.centerPoint.id !== undefined) {
          this.setMapCenter(this.$props.centerPoint)
        }
        // 开启鼠标滚轮缩放
        map.enableScrollWheelZoom(true)
        // 添加缩放控件
        // map.addControl(new BMapGL.ZoomControl())
        // 设置地图样式
        this.setMapStyle()
        // 添加标点
        this.addPoint(map, this.$props.point)
        // 添加覆盖物
        this.addPolygon(map, this.$props.polygon)
      })
    },
    // 添加单标点
    addOnePoint (latLngObj, isNotInit, that) {
      if (this.map) {
        if (this.$props.clearOverlays.flag) {
          that.color = '#D82109'
        }
        const _this = that || this
        // 标点图片
        let img
        // 标点图标对象
        let myIcon
        // 标注偏移量
        let offsetSize = 6
        // 是否非初始化时使用
        if (isNotInit) {
          switch (_this.color) {
            case '#ECF9FF':
              img = require('../assets/img/locationWhite.png')
              break
            case '#FFB936':
              img = require('../assets/img/locationYellow.png')
              break
            case '#46C88C':
              img = require('../assets/img/locationGreen.png')
              break
            case '#09C8EB':
              img = require('../assets/img/locationBlue.png')
              break
            case '#5C7BD9':
              img = require('../assets/img/locationPurple.png')
              break
            default:
              img = require('../assets/img/locationRed.png')
          }
          // eslint-disable-next-line no-undef
          myIcon = new BMapGL.Icon(img, new BMapGL.Size(30, 32))
          offsetSize = 18
          this.polygonIdArr.push(latLngObj.id)
        }
        // 坐标对象
        // eslint-disable-next-line no-undef
        const point = new BMapGL.Point(latLngObj.point[0], latLngObj.point[1])
        // 标点对象
        // eslint-disable-next-line no-undef
        const marker = new BMapGL.Marker(point, {icon: myIcon})
        // 为标点添加点击事件
        marker.addEventListener('click', function () {
          _this.$emit('onMarkerClick', latLngObj)
        })
        marker.id = latLngObj.id
        // 添加标点到地图中
        _this.map.addOverlay(marker)
        // 文本标注对象
        // eslint-disable-next-line no-undef
        const label = new BMapGL.Label(latLngObj.name, {
          position: point,
          // 设置标注偏移量
          // eslint-disable-next-line no-undef
          offset: new BMapGL.Size(0, offsetSize)
        })
        // 添加文本标注到地图中
        _this.map.addOverlay(label)
        // 文本标注样式
        label.setStyle({
          color: that.color === '#ECF9FF' ? '#7E8892' : '#FFFFFF',
          fontSize: '12px',
          padding: '2px 5px',
          border: '1px solid ',
          borderColor: that.color,
          background: that.color,
          fontWeight: 'bold',
          transform: 'translateX(-50%)',
          fontFamily: '微软雅黑'
        })
        // 添加信息窗口
        this.addInfoWindow(_this.map, marker, point, latLngObj)
      }
    },
    // 批量添加标点
    addPoint (map, pointArr) {
      const that = this
      for (const item of pointArr) {
        this.addOnePoint(item, false, that)
      }
    },
    // 删除覆盖物
    delOverlays (val, type) {
      if (this.map) {
        const allOverlay = this.map.getOverlays()
        if (val.length !== 0 && allOverlay.length) {
          for (const index in allOverlay) {
            if (type === 'point' && allOverlay[index].toString() === 'Marker' && allOverlay[index].id === val.id) {
              const i = this.polygonIdArr.indexOf(val.id)
              if (i !== -1) {
                this.polygonIdArr.splice(Number(i), 1)
                this.polygonDelFlag = false
                this.color = '#D82109'
              }
              // 删除标记点
              this.map.removeOverlay(allOverlay[index])
              // 删除文本标注
              this.map.removeOverlay(allOverlay[Number(index) + 1])
            }
            if (type === 'polygon' && allOverlay[index].toString() === 'Polygon' && val[0].id === allOverlay[index].id) {
              this.map.removeOverlay(allOverlay[index])
              this.polygonDelFlag = false
            }
          }
        }
      }
    },
    // 添加信息窗口
    addInfoWindow (map, marker, point, latLngObj) {
      const opts = {
        width: 250,
        height: 100,
        title: latLngObj.name,
        message: ''
      }
      const content = `<input type="button" id="btn" style="width: 220px;font-size: 16px;margin: 60px auto 0;background-color: #49C5E3" value="点击查看详情" />`
      // eslint-disable-next-line no-undef
      const infoWindow = new BMapGL.InfoWindow(content, opts)
      const that = this
      infoWindow.addEventListener('open', function () {
        document.getElementById('btn').onclick = function () {
          that.$router.push({
            path: '/xuexiao',
            query: {
              schoolId: latLngObj.id
            }
          })
        }
      })
      marker.addEventListener('click', function () {
        map.openInfoWindow(infoWindow, point)
      })
    },
    // 添加面覆盖物
    addPolygon (map, polygonArr) {
      for (const index in polygonArr) {
        // 地图点对象数组
        const pointObjArr = []
        // 组装点对象数组
        for (const item2 of polygonArr[index].arr) {
          // eslint-disable-next-line no-undef
          pointObjArr.push(new BMapGL.Point(item2[0], item2[1]))
        }
        // 实例化面对象
        // eslint-disable-next-line no-undef
        const polygon = new BMapGL.Polygon(pointObjArr, {
          // 边线颜色
          strokeColor: this.polygonColor[this.colorIndex],
          // 边线样式，solid或dashed
          strokeStyle: 'solid',
          // 边线宽度
          strokeWeight: 2,
          // 边线不透明度
          strokeOpacity: 1,
          // 填充颜色
          fillColor: this.polygonColor[this.colorIndex],
          // 填充不透明度
          fillOpacity: 0.3
        })
        polygon.id = polygonArr[index].id
        // 添加面对象到地图中
        map.addOverlay(polygon)
      }
    },
    // 取得[n,m]范围随机数
    randomNum (n, m) {
      let result = Math.random() * (m + 1 - n) + n
      while (result > m) {
        result = Math.random() * (m + 1 - n) + n
      }
      return result
    },
    // 获取颜色值
    getRandomColor () {
      const colorArr = ['#ECF9FF', '#FFB936', '#46C88C', '#09C8EB', '#5C7BD9']
      if (this.colorIndex < (Number(colorArr.length) - 1)) {
        this.colorIndex++
      } else {
        this.colorIndex = 0
      }
      return colorArr[this.colorIndex]
      // return '#' + ('00000' + ((Math.random() * 16777215 + 0.5) >> 0).toString(16)).slice(-6)
    },
    // 滚动事件
    handleScroll (e) {
      let direction = !(e.deltaY > 0)
      this.mapResize(direction)
    },
    // 重设地图缩放等级
    mapResize (type) {
      if (this.map) {
        type ? this.map.zoomIn() : this.map.zoomOut()
      }
    },
    // 设置地图主题
    setMapStyle () {
      if (this.map) {
        this.map.setMapStyleV2({
          styleId: 'c131d286db29abd746125d618aaad431'
        })
      }
    },
    // 设置地图中心及各角度
    setMapCenter (point) {
      if (this.map) {
        // eslint-disable-next-line no-undef
        this.map.centerAndZoom(new BMapGL.Point(point.point[0], point.point[1]), 18)
        // 设置地图旋转角度
        this.map.setHeading(64.5)
        // 设置地图的倾斜角度
        this.map.setTilt(77)
      }
    },
    // 返回地图对象
    getMapObj () {
      this.$emit('getMapObj', this.map)
    }
  },
  mounted () {
    this.initBMap()
  },
  beforeDestroy () {
    if (this.map) {
      this.map.destroy()
      this.map = null
    }
  }
}
</script>

<style scoped lang="less">
.box {
  height: 100%;
  position: relative;
  overflow: hidden;
}
#container {
  width: 100%;
  height: 100%;
  z-index: 1;
  opacity: .99;
}
/deep/ .BMap_bubble_pop {
  background-color: #14243E !important;
  border-color: #14243E !important;
}
/deep/ .BMap_bubble_title {
  color: #49C5E3 !important;
  font-size: 18px;
}
</style>
